package com.ztr.rabbitmq;

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;

import java.nio.charset.StandardCharsets;
import java.io.IOException;
import java.util.*;

import org.json.JSONArray;
import org.json.JSONObject;

public class ExchangeListFetcher {

    private static final String RABBITMQ_MANAGEMENT_URL = "http://192.168.195.128:15672/api/exchanges/%2f";
    private static final String RABBITMQ_USERNAME = "guest";
    private static final String RABBITMQ_PASSWORD = "guest";

    private static final String QUEUE_NAME_PATTERN = "queue_%d";

    /**
     * 主函数，用于通过HTTP请求获取RabbitMQ的交换机列表。
     * 使用Apache HttpClient库发送GET请求到RabbitMQ管理接口，并处理响应。
     * 需要在环境配置中提供RabbitMQ的管理URL、用户名和密码。
     *
     * @param args 命令行参数（未使用）
     * @throws IOException 如果发生I/O错误
     */
    public static void main(String[] args) throws Exception {
        // 使用默认配置创建HTTP客户端
        try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
            HttpGet request = new HttpGet(RABBITMQ_MANAGEMENT_URL);
            // 创建认证信息，并添加到请求头中
            String auth = RABBITMQ_USERNAME + ":" + RABBITMQ_PASSWORD;
            byte[] encodedAuth = Base64.getEncoder().encode(auth.getBytes(StandardCharsets.UTF_8));
            String authHeaderValue = "Basic " + new String(encodedAuth);
            request.setHeader("Authorization", authHeaderValue);
            // 执行HTTP请求并处理响应
            try (CloseableHttpResponse response = httpClient.execute(request)) {
                HttpEntity entity = response.getEntity();
                if (response.getStatusLine().getStatusCode() == 200) {
                    // 如果响应状态码为200（成功），则解析响应体
                    String responseBody = EntityUtils.toString(entity);
                    // 这里解析JSON响应以获取交换机列表，然后打印出来作为示例
                    Map<String, String> exchangeMap = extractExchangeMap(responseBody);
                    System.out.println(exchangeMap);
                } else {
                    // 如果响应状态码非200，打印错误信息
                    System.err.println("Failed to fetch exchange list. Status code: " + response.getStatusLine().getStatusCode());
                }
            }
        }
    }

    /**
     * 从JSON字符串中提取交易所信息并存储到Map中。
     *
     * @param jsonString 表示交易所信息的JSON字符串。
     * @return 返回一个Map，其中键为交易所名称，值为交易所类型。
     */
    private static Map<String, String> extractExchangeMap(String jsonString) {
        // 创建一个空的Map来存储交易所信息
        Map<String, String> exchangeMap = new HashMap<>();
        // 将JSON字符串解析为JSONArray
        JSONArray jsonArray = new JSONArray(jsonString);

        // 遍历JSONArray，提取每个交易所的名称和类型
        for (int i = 0; i < jsonArray.length(); i++) {
            JSONObject jsonObject = jsonArray.getJSONObject(i);
            String name = jsonObject.getString("name");
            String type = jsonObject.getString("type");
            exchangeMap.put(name, type);
        }

        return exchangeMap;
    }

    /**
     * 创建名为'amq.ztr'的topic交换机，并创建三个队列，分别绑定到该交换机，使用指定的路由键。
     *
     * @throws Exception 如果在与RabbitMQ交互过程中发生异常
     */
    public static void createExchangeAndQueues() throws Exception {
        ConnectionFactory factory = new ConnectionFactory();
        factory.setHost("http://192.168.195.128:15672"); // 替换为RabbitMQ服务器地址
        factory.setUsername("guest");
        factory.setPassword("guest");

        try (Connection connection = factory.newConnection();
             Channel channel = connection.createChannel()) {

            // 创建名为'amq.ztr'的topic交换机
            channel.exchangeDeclare("amq.ztr", "topic", true);

            // 创建并绑定三个队列到'amq.ztr'交换机
            String[] routingKeys = {"ztr.#", "*.ztr.*", "#.ztr.#"};
            for (int i = 0; i < routingKeys.length; i++) {
                String queueName = String.format(QUEUE_NAME_PATTERN, i);
                channel.queueDeclare(queueName, true, false, false, null);
                channel.queueBind(queueName, "amq.ztr", routingKeys[i]);
                System.out.printf("Created queue '%s' bound to 'amq.ztr' with routing key '%s'\n", queueName, routingKeys[i]);
            }
        }
    }

}
